package com.kfm.singleton;


import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class SimpleSingleton {

    public static void main(String[] args) {
        InnerClassSingleton instance = InnerClassSingleton.getInstance();
        System.out.println(instance);

        // 反射
//        Class<InnerClassSingleton> innerClassSingletonClass = InnerClassSingleton.class;
//        try {
//            Constructor<InnerClassSingleton> constructor = innerClassSingletonClass.getDeclaredConstructor();
//            constructor.setAccessible(true);
//
//            InnerClassSingleton innerClassSingleton = constructor.newInstance();
//            InnerClassSingleton innerClassSingleton2 = constructor.newInstance();
//
//            System.out.println(instance);
//            System.out.println(innerClassSingleton);
//            System.out.println(innerClassSingleton2);
//
//        } catch (NoSuchMethodException e) {
//            e.printStackTrace();
//        } catch (InvocationTargetException e) {
//            e.printStackTrace();
//        } catch (InstantiationException e) {
//            e.printStackTrace();
//        } catch (IllegalAccessException e) {
//            e.printStackTrace();
//        }

    }
}

// 懒汉
class LazySingleton {

    private LazySingleton() {
    }

    private static LazySingleton instannce;

    public static LazySingleton getInstance() {
        if (instannce == null) {
            instannce = new LazySingleton();
        }
        return instannce;
    }
}

// 双重检查锁
class DoubleCheckedSingleton {

    private DoubleCheckedSingleton() {
    }

    private static volatile DoubleCheckedSingleton instance;

    public static DoubleCheckedSingleton getInstance() {
        synchronized (DoubleCheckedSingleton.class) {
            if (instance == null) {
                synchronized (DoubleCheckedSingleton.class) {
                    // 防止指令重排序
                    instance = new DoubleCheckedSingleton();
                }
            }
        }
        return instance;
    }
}


// 饿汉
class HungrySingleton {

    private HungrySingleton() {
    }

    private static final HungrySingleton instance = new HungrySingleton();

    public static HungrySingleton getInstance() {
        return instance;
    }
}

// 枚举
enum EnumSingleton {
    A, B, C, D;
}

// 静态内部类
class InnerClassSingleton {

    private InnerClassSingleton() {
        if (StaticInnerClass.instance != null) {
            throw new RuntimeException("错误使用");
        }
    }

    private static class StaticInnerClass {
        private static final InnerClassSingleton instance = new InnerClassSingleton();
    }

    public static InnerClassSingleton getInstance() {
        return StaticInnerClass.instance;
    }

}

